/**
 * 
 */
package hu.myai.util;

import hu.myai.model.db.AxHistory;
import hu.myai.model.sp.HighStockPivot;
import hu.myai.model.sp.LowStockPivot;

import java.util.List;

public class Charting {

	// private static final ILogger log =
	// LoggerFactory.getLogger(Charting.class);

	private int maxRange = 5;

	private String symbol;

	public Charting(String symbol) {
		this.symbol = symbol;
	}

	/**
	 * Get the first maximum. There is no higher maximum in the given range
	 * 
	 * @param historyArray
	 *            list of AxHistory elements
	 * @param range
	 *            no another maximum within element range
	 * @return the highest AxHistory object
	 */
	public AxHistory getFirstMax(List<AxHistory> historyList, int range) {

		int index = 0;
		double maxHigh = historyList.get(index).getHigh();
		int maxHighIndex = index;

		for (AxHistory history : historyList) {
			if (history.getHigh() >= maxHigh && history.getHigh() > 0.0) {
				maxHigh = history.getHigh();
				maxHighIndex = index;
				// log.debug("  max: "+maxHigh);
			}
			if (index - maxHighIndex > range) {
				break;
			}
			index++;
		}
		// log.debug("-> "+maxHigh);
		return historyList.get(maxHighIndex);
	}

	/**
	 * Get the first minimum. There is no lower minimum in the given range
	 * 
	 * @param historyArray
	 *            list of AxHistory elements
	 * @param range
	 *            no another minimum within element range
	 * @return the lowest AxHistory object
	 */
	public AxHistory getFirstMin(List<AxHistory> historyList, int range) {

		int index = 0;
		double minLow = historyList.get(index).getLow();
		int minLowIndex = index;

		for (AxHistory history : historyList) {
			if (history.getLow() <= minLow && history.getLow() > 0.0) {
				minLow = history.getLow();
				minLowIndex = index;
				// log.debug("  min: "+minLow);
			}
			if (index - minLowIndex > range) {
				break;
			}
			index++;
		}
		// log.debug("-> "+minLow);
		return historyList.get(minLowIndex);

	}

	/**
	 * This get the first low isolated peek
	 * 
	 * @param historyList
	 *            contains the input AxHistory list
	 * @return the isolated AxHistory of the lowest peek
	 */
	public AxHistory getFirstLowPivo(List<AxHistory> historyList) {

		AxHistory firstMaxHistory = getFirstMax(historyList, maxRange);
		int index = historyList.lastIndexOf(firstMaxHistory);

		List<AxHistory> historyFromMax = historyList.subList(index, historyList.size());

		return getFirstMin(historyFromMax, maxRange);

	}

	/**
	 * This get the first high isolated peek
	 * 
	 * @param historyList
	 *            contains the input AxHistory list
	 * @return the isolated AxHistory of the highest peek
	 */
	public AxHistory getFirstHighPivo(List<AxHistory> historyList) {

		AxHistory firstMinHistory = getFirstMin(historyList, maxRange);
		int index = historyList.lastIndexOf(firstMinHistory);

		List<AxHistory> historyFromMin = historyList.subList(index, historyList.size());

		return getFirstMax(historyFromMin, maxRange);

	}

	/**
	 * @param historyList
	 *            filter out the high and low pivots and make a private array
	 *            out of it
	 */
	public Trend getPivoSequence(List<AxHistory> historyList) {

		int indexHigh = historyList.lastIndexOf(getFirstHighPivo(historyList));
		int indexLow = historyList.lastIndexOf(getFirstLowPivo(historyList));

		// check what shape is the first isolated high or isolated low
		List<AxHistory> workingCopyHistory;

		// start the analysis at a local up-trend
		if (indexHigh > indexLow) {
			workingCopyHistory = historyList.subList(indexLow, historyList.size());
		} else {
			workingCopyHistory = historyList;
		}

		Trend stockPivotsList = new Trend(symbol, historyList);

		for (int i = 0; i < workingCopyHistory.size() - maxRange;) {

			workingCopyHistory = workingCopyHistory.subList(i, workingCopyHistory.size());
			AxHistory nextMaxAxHistory = getFirstMax(workingCopyHistory, maxRange);

			// log.debug("max: "+nextMaxAxHistory);
			i = workingCopyHistory.lastIndexOf(nextMaxAxHistory);
			stockPivotsList.add(new HighStockPivot(nextMaxAxHistory));

			// if a candle is open a local low and close on local high
			if (i == 0)
				i++;

			workingCopyHistory = workingCopyHistory.subList(i, workingCopyHistory.size());
			AxHistory nextMinHistory = getFirstMin(workingCopyHistory, maxRange);
			// log.debug("min: "+nextMinHistory);

			i = workingCopyHistory.lastIndexOf(nextMinHistory);
			stockPivotsList.add(new LowStockPivot(nextMinHistory));

			// if a candle is open a local high and close on local low
			if (i == 0)
				i++;
		}

		// TODO: remove double button and double tops.
		return stockPivotsList;
	}
}
